


class IAERenderContext
{
	virtual void Activate( void ) = 0;

	/// \brief
	///   Returns this context's target rendering size
	/// 
	/// \param iWidth
	///   Out: Width of the render context.
	/// 
	/// \param iHeight
	///   Out: Height of the render context.
	virtual void GetTargetSize( AEINT32 &nWidth, AEINT32 &nHeight ) const = 0;

	/// \brief
	///   Specifies the viewport to be used for this render context
	/// 
	/// By default, the viewport will be set to use the whole render target size specified with
	/// SetSize (when rendering to the back buffer), or to the size of the renderable texture which
	/// is set as render target (when rendering to a texture). This function can be used if you only
	/// want to render to a part of the render target.
	/// 
	/// \param iPosX
	///   X coordinate of upper left corner of the viewport, in pixels.
	/// 
	/// \param iPosY
	///   Y coordinate of upper left corner of the viewport, in pixels.
	/// 
	/// \param iWidth
	///   Width of the viewport, in pixels.
	/// 
	/// \param iHeight
	///   Height of the viewport, in pixels.
	virtual void SetViewport( AEINT32 nPosX, AEINT32 nPosY, AEINT32 nWidth, AEINT32 nHeight ) = 0;

	/// \brief
	///   Returns the viewport to be used for this render context
	/// 
	/// \param iPosX
	///   Out: X coordinate of upper left corner of the viewport, in pixels.
	/// 
	/// \param iPosY
	///   Out: Y coordinate of upper left corner of the viewport, in pixels.
	/// 
	/// \param iWidth
	///   Out: Width of the viewport, in pixels.
	/// 
	/// \param iHeight
	///   Out: Height of the viewport, in pixels.
	virtual void GetViewport( AEINT32 &nPosX, AEINT32 &nPosY, AEINT32 &nWidth, AEINT32 &nHeight ) const = 0;

	/// \brief
	///   Sets the desired horizontal or vertical field of view of this render context in degrees.
	/// 
	/// If either FOV value is 0.0f, it will be computed automatically using the other value and the current
	/// display aspect ratio.
	/// 
	/// \param fFovX
	///   Horizontal field of view in degrees.
	/// 
	/// \param fFovY
	///   Vertical field of view in degrees.
	virtual void SetFOV( float fFovX, float fFovY = 0.0f ) = 0;

	/// \brief
	///   Returns the field of view of this render context
	/// 
	/// Values are specified in degrees.
	/// 
	/// \param fFovX
	///   Out: Field of View in horizontal direction.
	/// 
	/// \param fFovY
	///   Out: Field of View in vertical direction.
	virtual void GetFOV( float &fFovX, float &fFovY ) const = 0;

	/// \brief
	///   Sets the near and far clip distances of the render context
	/// 
	/// \param fNearClipDist
	///   Near clip distance for this render context.
	///
	/// \param fFarClipDist
	///   Far clip distance for this render context.
	virtual void SetClipPlanes( float fNearClipDist, float fFarClipDist ) = 0;

	/// \brief
	///   Returns the near and far clip distances of the render context
	/// 
	/// \param fNearClipDist
	///   Reference that receives the current near clip distance
	///
	/// \param fFarClipDist
	///   Reference that receives the current far clip distance
	virtual void GetClipPlanes( float &fNearClipDist, float &fFarClipDist ) const = 0;


	/// \brief
	///   Method to set the render target(s) for this context
	/// 
	/// This function only sets the color buffers of the render target; the depth/stencil target may
	/// be set with SetDepthStencilTarget.
	/// 
	/// This function will also adjust the viewport to the render target's size.
	/// 
	/// Note that when using multiple render targets, all render targets have to have the same size.
	/// 
	/// Note that the passed renderable texture has to be in a valid target format for color buffer
	/// rendering (the exact requirements depend on the target platform, hardware, and drivers). 
	/// 
	/// Some platforms/hardware configurations may add additional requirements, such as all
	/// simultaneous render targets having to be in the same format.
	/// 
	/// The number of simultaneous render targets supported depends on the platform/hardware
	/// configuration.
	/// 
	/// Is is valid to specify NULL as pTexObject to disable a specific render target; however, note
	/// that the DirectX9 renderer does not allow setting the render target for index 0 to NULL.
	/// 
	/// Note that cube map render targets have to be set using the SetRenderTargetCubeMap method
	/// instead. 2D Array Texture render targets have to be set using the
	/// SetRenderTarget2DArrayTexture method (DirectX10/11 only).
	/// 
	/// \param iRenderTargetIndex
	///   Index of the render target to set
	/// 
	/// \param pTexObject
	///   Has to be either NULL or a renderable texture object.
	/// 
	/// \return
	///   bool: true if setting the render target was successful
	virtual bool SetRenderTarget( AEINT32 nRenderTargetIndex, const IAERenderableTexture *lpTexObject ) = 0;

	/// \brief
	///   Function that returns the render target texture of this context
	/// 
	/// The render target can be set using the SetRenderTarget method.
	/// 
	/// Note that if this function returns NULL, this only means that there is no renderable texture
	/// set as a render target for this context. If e.g. VisRenderContext_cl::SetRenderSurface has
	/// been used to directly set a DirectX surface as render target, this method will return NULL.
	/// Similarly, calling this method on the main render context will also return NULL.
	/// 
	/// In order to determine whether the returned object is a renderable cube map, a renderable 2D
	/// texture, or a renderable 2D texture array, simply check the type of the returned
	/// VTextureObject (GetTextureType), or call IsCubemap() and IsTexture2DArray() or it. You may
	/// then cast the object to the respective target type (e.g. VisRenderableCubemap_cl,
	/// VisRenderableTexture_cl).
	/// 
	/// \param iRenderTargetIndex
	///   Render Target index for which to return the render target texture (default is 0).
	/// 
	/// \param pFaceOrIndex
	///   If not NULL and the render target texture is a cube map, this will contain the face index
	///   of the cube map which is set as the render target for this context. If not NULL and the
	///   render target is a 2D texture array, this will contain the array index of the texture array
	///   which is set as the render target for this context. In DirectX10/11, if the render target is a
	///   cube map or array texture and this value is -1, this means that the render target is not a
	///   specific face or slice of the cubemap/array texture, but it is the complete texture object.
	///   In this case, the face or array index to render to can be chosen in the geometry shader.
	/// 
	/// \return
	///   VTextureObject *: NULL or the offscreen render target (renderable texture)
	virtual IAETexture *GetRenderTarget( AEINT32 nRenderTargetIndex = 0, AEINT32 *lpFaceOrIndex = NULL ) const = 0;


	/// \brief
	///   Returns the number of active render targets in this render context.
	virtual AEUINT32 GetNumRenderTargets( void ) const = 0;


	/// \brief
	///   Function to set the render flags for this context
	/// 
	/// Do not call this function inside a render loop.
	/// 
	/// \param iFlags
	///   Set of render flags that may be provided for render contexts.
	///   See enum VRenderContextFlags.
	virtual void SetRenderFlags( AEINT32 nFlags ) = 0;

	/// \brief
	///   Returns the context's render flags
	/// 
	/// \return
	///   int: Render flags.
	/// 
	/// \sa SetRenderFlags
	virtual AEINT32 GetRenderFlags( void ) const = 0;


	/// \brief
	///   Sets the render loop of this render context
	/// 
	/// Render contexts may have their own render loop implementation. The render loop can be set
	/// using this method.
	/// 
	/// By default, render contexts use the Vision engine's default render loop (VisionRenderLoop).
	/// 
	/// \param pRenderLoop
	///   Render loop for this render context
	virtual bool SetRenderLoop( IAERenderLoop *lpRenderLoop ) = 0;

	/// \brief
	///   Gets the render loop for this render context
	/// 
	/// \return
	///   IVisRenderLoop_cl *: Render loop for this render context
	virtual IAERenderLoop *GetRenderLoop( void ) const = 0;



	/// \brief
	///   Sets a new pre-defined projection matrix type
	/// 
	/// If the type is VIS_PROJECTIONTYPE_PERSPECTIVE or VIS_PROJECTIONTYPE_ORTHOGRAPHIC then the
	/// context takes care of creating the appropriate projection matrix. These two modes are also
	/// gracefully handled by the standard visibility implementations.
	/// 
	/// GetProjectionMatrix returns the projection matrix for the respective mode.
	/// 
	/// The default is mode for every new context is VIS_PROJECTIONTYPE_PERSPECTIVE.
	/// 
	/// The VIS_PROJECTIONTYPE_ORTHOGRAPHIC mode can be used for top views (used in vForge for
	/// instance)
	/// 
	/// \param eType
	///   The new mode constant. The following modes are supported:
	///   \li VIS_PROJECTIONTYPE_PERSPECTIVE: A perspective projection matrix is used defined by clip
	///     planes and FOV of this context.
	/// 
	///   \li VIS_PROJECTIONTYPE_ORTHOGRAPHIC: An orthographic projection matrix is used defined by
	///     the orthographic size of this context.
	/// 
	///   \li VIS_PROJECTIONTYPE_CUSTOM: The projection matrix is a custom matrix that needs to be
	///     set via SetCustomProjectionMatrix.
	/// 
	/// \sa VisRenderContext_cl::SetFOV
	/// \sa VisRenderContext_cl::SetClipPlanes
	/// \sa VisContextCamera_cl::GetInverseEyeMatrix
	virtual void SetProjectionType( AEProjectionType eType ) = 0;

	/// \brief
	///   Returns the projection type (VisProjectionType_e) of this context. See SetProjectionType
	virtual AEProjectionType GetProjectionType( void ) const = 0;

	/// \brief
	///   Sets the render context's render priority
	/// 
	/// The priority can be used to ensure a specific render order of render contexts which depend on
	/// each other. For instance, a shadow context will typically have a lower priority than the main
	/// scene context, since the shadow results are needed for rendering the scene and lower
	/// priorities are rendered first.
	/// 
	/// The priorities are taken into account by the VisRenderContextManager_cl class, which
	/// automatically resorts contexts based on their priority. The resulting list is taken as input
	/// by the VisionApp_cl::Run method, which iterates over the render contexts and renders them.
	/// Since your application does not have to use the VisionApp_cl class, you can naturally
	/// implement similar functionality yourself.
	/// 
	/// The default priority is 0.0f
	/// 
	/// \param fPriority
	///   Render priority of the render context
	virtual void SetPriority( float fPriority ) = 0;

	/// \brief
	///   Returns the render context's render priority
	/// 
	/// The priority has been previously set with SetPriority.
	/// 
	/// \return
	///   float fPriority: Render priority of the render context
	virtual float GetPriority( void ) const = 0;

	/// \brief
	///   Enables/disables rendering for this render context
	/// 
	/// This state is only relevant when using the VisionApp_cl::Run method. This method checks
	/// whether rendering is enabled for each render context, and only activates and renders it if
	/// this is the case. Otherwise, the render context is simply ignored.
	/// 
	/// In case you are not using the VisionApp_cl class and still want to disable/enable rendering
	/// to specific render contexts using this method, you have to query the state manually using the
	/// GetRenderingEnabled function.
	/// 
	/// \param bStatus
	///   true to enable rendering, false to disable it
	virtual void SetRenderingEnabled( bool bEnabled ) = 0;

	/// \brief
	///   Returns whether rendering is enabled for this render context
	/// 
	/// \return
	///   bool bStatus: true to enable rendering, false to disable it
	virtual bool GetRenderingEnabled( void ) const = 0;

	virtual void ReleaseContext( void ) = 0;
	///
	/// @name Low-level Platform-specific Render Target Handling
	/// @{
	///

#if defined (AE_OPENGL) || defined (AE_GLES1) || defined (AE_GLES2)
	virtual void SetRenderSurface( AEINT32 nTargetIndex, AEUINT32 nColorTargetHandle, AEUINT32 nColorTextureHandle = 0 ) = 0;
	virtual void GetRenderSurface( AEINT32 nTargetIndex, AEUINT32 &nColorHandle);
	virtual void SetDepthStencilSurface( AEUINT32 nDepthStencilHandle, bool bUseStencil = false, AEUINT32 nDepthStencilTextureHandle = 0 ) = 0;
	virtual void GetDepthStencilSurface( AEUINT32 &nDepthStencilHandle ) = 0;
	virtual void CreateFrameBufferObject( void ) = 0;
	virtual void DeleteFrameBufferObject( void ) = 0;
#endif

};
